<?php

namespace app\common\model\mall\order;

use think\Exception;
use think\Model;
use think\Db;
use app\common\model\mall\goods\Cat;
use addons\mall\model\User;
use app\common\model\mall\oper\Msgtpl;
use app\common\model\mall\oper\Notification;
use addons\mall\library\Service;
use traits\model\SoftDelete;
use think\Hook;

class Order extends Model
{
    // 表名
    protected $name = 'mall_order_order';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = false;
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [
        'deliverType_text',
        'payType_text',
        'orderSrc_text',
        'prom_type_text',
        'noticeDeliver_text',
        'user_id_text',
        'status_text'
    ];

    use SoftDelete;

    protected static function init()
    {
        $config = get_addon_config('mall');

        //发送消息提醒卖家
        self::afterWrite(function ($row) use ($config) {
            //替换消息模板参数，获取消息内容
            if(isset($row["status"]) && in_array($row["status"],["unpay","undeliver","canceled","unappraise","rejected","unreceive"])) {
                $find = ['${ORDER_NO}'];
                $replace = [$row['orderNo']];
                switch ($row["status"]) {
                    case "unpay":
                        $content = Msgtpl::getMsgByTpl('ORDER_SUBMIT', $find, $replace);
                        $title = "客户已下单";
                        break;
                    case "undeliver":
                        $content = Msgtpl::getMsgByTpl('ORDER_HASPAY', $find, $replace);
                        $title = "客户已付款";
                        break;
                    case "canceled":
                        $find = ['${ORDER_NO}', '${REASON}'];
                        $reasonData = self::getCancelreasonList()[$row['cancelReason']];
                        $replace = [$row['orderNo'], $reasonData];
                        $content = Msgtpl::getMsgByTpl('ORDER_CANCEL', $find, $replace);
                        $title = "订单被取消";
                        break;
                    case "unappraise":
                        $content = Msgtpl::getMsgByTpl('ORDER_RECEIVE', $find, $replace);
                        $title = "客户已收货";
                        break;
                    case "rejected":
                        $reasonData = self::getRejectreasonList()[$row['rejectReason']];
                        $find = ['${ORDER_NO}', '${REASON}'];
                        $replace = [$row['orderNo'], $reasonData];
                        $content = Msgtpl::getMsgByTpl('ORDER_REJECT', $find, $replace);
                        $title = "订单被拒收";
                        break;
                    case "unreceive":
                        $find = ['${ORDER_NO}','${EXPRESS_NO}'];
                        $replace = [$row['orderNo'],($row['expressNo']=='')?'无':$row['expressNo']];
                        $content = Msgtpl::getMsgByTpl('ORDER_DELIVERY', $find, $replace);
                        $title = "商家已发货";
                        break;
                }
                //设置接收人
                if(in_array($row["status"],["unpay","undeliver","canceled","unappraise","rejected"])) {
                    $to_user_id = \app\common\model\mall\shop\Shop::getFieldById($row['shop_id'], "user_id");
                    $tomobile = \app\common\model\mall\shop\Extra::getFieldByShopId($row['shop_id'], "applyLinkTel");
                }
                elseif(in_array($row["status"],["unreceive"])){
                    $to_user_id = $row["user_id"];
                    $tomobile = \app\common\model\User::getFieldById($row["user_id"], "mobile");
                }
                if ($content != '') {
                    //新增订单日志
                    $logOrder = [];
                    $logOrder['order_id'] = $row['id'];
                    $logOrder['status'] = $row["status"];
                    $logOrder['logContent'] = $content;
                    $logOrder['logUserId'] = cookie("uid") ? cookie("uid") : 0;
                    $logOrder['logType'] = 0;
                    $logOrder['logTime'] = date('Y-m-d H:i:s');
                    db('mall_order_log')->insert($logOrder);

                    Notification::record($title, $content, $row["status"], "order", $row['id'], $to_user_id);
                    $template_id = 1;
                    Hook::listen('vbot_send_msg', $template_id, [
                        'content'         => $content,
                        'at_mobiles'     => $tomobile,
                        'is_atall'       => 0,
                    ]);
                }
            }
        });
    }

    public function getUserIdTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['user_d']) ? $data['user_d'] : '');
        $name = "";
        if($value){
            $name = \app\common\model\User::where("id","=",$value)->field("nickname,username")->find();
            $name = $name["nickname"]!=""?$name["nickname"]:$name["username"];
        }
        return $name;
    }

    public function getDelivertypeList()
    {
        return ['0' => __('Delivertype 0'),'1' => __('Delivertype 1')];
    }

    public function getPaytypeList()
    {
        return ['0' => __('Paytype 0'),'1' => __('Paytype 1')];
    }

    public static function getOrdersrcList()
    {
        return ['1' => __('Ordersrc 1'),'2' => __('Ordersrc 2'),'3' => __('Ordersrc 3'),'4' => __('Ordersrc 4'),'5' => __('Ordersrc 5')];
    }

    public static function getCancelreasonList()
    {
        return ['1' => __('Cancelreason 1'),'2' => __('Cancelreason 2'),'3' => __('Cancelreason 3'),'4' => __('Cancelreason 4'),'5' => __('Cancelreason 5')];
    }

    public static function getRejectreasonList()
    {
        return ['1' => __('Rejectreason 1'),'2' => __('Rejectreason 2'),'3' => __('Rejectreason 3'),'99' => __('Rejectreason 99')];
    }

    public function getPromTypeList()
    {
        return ['0' => __('Prom_type 0'),'4' => __('Prom_type 4'),'5' => __('Prom_type 5'),'6' => __('Prom_type 6')];
    }

    public function getNoticedeliverList()
    {
        return ['0' => __('Noticedeliver 0'),'1' => __('Noticedeliver 1')];
    }

    public function getStatusList()
    {
        return ['unpay' => __('Unpay'),'undeliver' => __('Undeliver'),'unreceive' => __('Unreceive'),'finished' => __('Finished'),'canceled' => __('Canceled'),'rejected' => __('Rejected'),'unappraise' => __('Unappraise')];
    }

    public function getDelivertypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['deliverType']) ? $data['deliverType'] : '');
        $list = $this->getDelivertypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getPaytypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['payType']) ? $data['payType'] : '');
        $list = $this->getPaytypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getOrdersrcTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['orderSrc']) ? $data['orderSrc'] : '');
        $list = $this->getOrdersrcList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    public function getPromTypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['prom_type']) ? $data['prom_type'] : '');
        $list = $this->getPromTypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    public function getNoticedeliverTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['noticeDeliver']) ? $data['noticeDeliver'] : '');
        $list = $this->getNoticedeliverList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    public function getStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
        $list = $this->getStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    /**
     * 根据订单批号获取订单信息
     */
    public function getByUnique($uId=0){
        $orderNo = input('orderNo');
        $isBatch = (int)input('isBatch/d',1);
        $user_id = cookie('uid')?cookie('uid'):$uId;
        if($isBatch==1){
            $w = ['user_id'=>$user_id,'orderunique'=>$orderNo];
        }else{
            $w = ['user_id'=>$user_id,'orderNo'=>$orderNo];
        }
        $rs = $this->where($w)
            ->field('id orderId,orderNo,payType,needPay,orderunique,deliverMoney,
                    userName,userPhone,userAddress')->select();

        $data = [];
        $data['orderunique'] = $orderNo;
        $data['list'] = [];
        $payType = 0;
        $totalMoney = 0;
        $order_ids = [0];
        foreach ($rs as $key =>$v){
            if($v['payType']==1) $payType = 1;
            $totalMoney = $totalMoney + $v['needPay'];
            $order_ids[] = $v['orderId'];
            $data['list'][] = $v;
        }
        $data['totalMoney'] = $totalMoney;
        $data['payType'] = $payType;
        //获取商品信息
        $goods = Db::name('mall_order_goods')->alias("og")
            ->join("__MALL_GOODS_GOODS__ gg",'og.goods_id=gg.id','LEFT')
            ->field("og.id,og.order_id,og.goods_id,og.goodsNum,og.goodsSpecNames,
                og.goodsPrice,og.commissionRate,gg.goodsname,gg.goodsimg")
            ->where('order_id','in',$order_ids)->select();
        foreach ($goods as $key =>$v){
            $data['goods'][$v['order_id']][] = $v;
        }
        return $data;
    }

    /**
     * 获取订单详情
     */
    public function detail($order_id){
        $user_id = (int)cookie('uid');
        if(!$order_id) $order_id = cookie("order_id");
        //$shop_id = (int)cookie('shop_id');
        $orders = self::alias('o')->with("goods,log")
            ->join('__MALL_OPER_EXPRESS__ e','o.express_id=e.id','left')
            ->join('__MALL_ORDER_REFUND__ orf ','o.id=orf.order_id','left')
            ->where('o.id',$order_id)
            ->field('o.*,e.name,orf.id refundId,orf.refundRemark,orf.refundStatus,orf.refundTime,orf.backMoney,orf.backMoney')
            ->find();
        if(empty($orders)) return [];
        $orders["payTypeName"]=$this->getPaytypeList()[$orders["payType"]];
        $orders["deliverTypeName"]=$this->getPaytypeList()[$orders["deliverType"]];
        // 获取收货地址
        $areaNames = \app\common\model\mall\oper\Area::where("id","in",$orders['area_ids'])
            ->column("name");
        $orders['userAddress'] = implode('',$areaNames).$orders['userAddress'];

        //获取订单日志
        $logFilter = [];
        foreach ($orders['log'] as $key => $v) {
            $logFilter[] = $v['status'];
        }

        //如果是虚拟商品
        if($orders['orderType']==1){
            foreach ($orders['goods'] as $key => $v) {
                $orders['goods'][$key]['extraJson'] = json_decode($v['extraJson'],true);
            }
        }
        return $orders;
    }

    /**
     * 修改订单价格
     */
    public function editOrderMoney($uId=0, $sId=0){
        $order_id = input('post.id');
        $orderMoney = (float)input('post.orderMoney');
        $user_id = ($uId==0)?(int)cookie('uid'):$uId;
        $shop_id = ($sId==0)?(int)cookie('shop_id'):$sId;
        if($orderMoney<0.01)throw new Exception("订单价格不能小于0.01");
        Db::startTrans();
        try{
            //修改订单价格前执行勾子
            hook('beforeEditOrderMoney',['order_id'=>$order_id,"orderMoney"=>$orderMoney]);
            $data = array();
            $data["realTotalMoney"] = $orderMoney;
            $data["needPay"] = $orderMoney;
            $data["payRand"] = array("exp","payRand+1");
            $result = $this->where(['order_id'=>$order_id,'shop_id'=>$shop_id,'status'=>'unpay'])->update($data);
            
            if(false !== $result){
                //新增订单日志
                $logOrder = [];
                $logOrder['order_id'] = $order_id;
                $logOrder['status'] = 'unpay';
                $logOrder['logContent'] = "商家修改订单价格为：".$orderMoney;
                $logOrder['logUserId'] = $user_id;
                $logOrder['logType'] = 0;
                $logOrder['logTime'] = date('Y-m-d H:i:s');
                Db::name('log_orders')->insert($logOrder);
                Db::commit();
                return $result;
            }
        }catch (\Exception $e) {
            Db::rollback();
            throw new Exception('操作失败',-1);
        }
    }

    /**
     * 检查订单是否已支付
     */
    public function checkOrderPay (){
        $user_id = (int)cookie('uid');
        $orderNo = input("orderNo");
        $isBatch = (int)input("isBatch");
        $rs = array();
        $where = ["user_id"=>$user_id,"status"=>"unpay","payis"=>0,"payType"=>1];
        if($isBatch==1){
            $where['orderunique'] = $orderNo;
        }else{
            $where['orderNo'] = $orderNo;
        }
        $rs = $this->field('order_id,orderNo')->where($where)->select();
        if(count($rs)>0){
            return $rs;
        }else{
            throw new Exception('订单已支付');

        }
    }
    
    /**
     * 检查订单是否已支付
     */
    public function checkOrderPay2 ($obj){
        $user_id = $obj["user_id"];
        $orderNo = $obj["orderNo"];
        $isBatch = $obj["isBatch"];
        $rs = array();
        $where = ["user_id"=>$user_id,"status"=>"unpay","payis"=>0,"payType"=>1];
        if($isBatch==1){
            $where['orderunique'] = $orderNo;
        }else{
            $where['orderNo'] = $orderNo;
        }
        $rs = $this->field('order_id,orderNo')->where($where)->select();
        if(count($rs)>0){
            return $rs;
        }else{
            throw new Exception('订单已支付',-1);
        }
    }

    /**
     * 虚拟商品支付处理
     */
    public function handleVirtualGoods($order_id){
        $order= Db::name('mall_order_order')->alias('o')->join('__MALL_SHOP_SHOP__ s','o.shop_id=s.shop_id ','inner')
            ->where('order_id',$order_id)->field('order_id,orderNo,o.shop_id,s.user_id,o.user_id ouser_id,o.realTotalMoney,o.payFrom')
            ->find();
        //新增订单日志
        $logOrder = [];
        $logOrder['order_id'] = $order['order_id'];
        $logOrder['status'] = "unreceive";
        $logOrder['logContent'] = "商家已发货";
        $logOrder['logUserId'] = $order['user_id'];
        $logOrder['logType'] = 0;
        $logOrder['logTime'] = date('Y-m-d H:i:s');
        Db::name('mall_order_log')->insert($logOrder);
        $logOrder = [];
        $logOrder['order_id'] = $order['order_id'];
        $logOrder['status'] = "unappraise";
        $logOrder['logContent'] = "用户已收货";
        $logOrder['logUserId'] = $order['ouser_id'];
        $logOrder['logType'] = 0;
        $logOrder['logTime'] = date('Y-m-d H:i:s');
        Db::name('mall_order_log')->insert($logOrder);
        //修改订单状态
        Db::name('mall_order_order')->where('id',$order['order_id'])->update(['status'=>'unappraise','deliveryTime'=>date('Y-m-d H:i:s'),'receiveTime'=>date('Y-m-d H:i:s')]);
        //分配卡券号
        $orderGoods = Db::name('mall_order_goods')->where(['order_id'=>$order['order_id'],'goodsType'=>1])->field('id,goodsname,extraJson')->find();
        $cardIds = [];
        $extraJson = json_decode($orderGoods['extraJson'],true);
        foreach ($extraJson as $ogextra) {
            $cardIds[] = $ogextra['cardId'];
        }
        $cards = model('app/common/model/mall/goods/Virtual')->where('id','in',$cardIds)->field('id,cardNo,cardPwd')->select();
        $cardmap = [];
        foreach ($cards as $card) {
            $cardmap[$card['id']] = $card;
        }
        $ogcards = [];
        $extra = json_decode($orderGoods['extraJson'],true);
        foreach ($extra as $ogextra) {
            $ogextra['cardId'] = $cardmap[$ogextra['cardId']]['id'];
            $ogextra['cardNo'] = $cardmap[$ogextra['cardId']]['cardNo'];
            $ogextra['cardPwd'] = $cardmap[$ogextra['cardId']]['cardPwd'];
            $ogextra['isUse'] = 0;
            $ogcards[] = $ogextra;
        }
        Db::name('mall_order_goods')->where('id',$orderGoods['id'])->update(['extraJson'=>json_encode($ogcards)]);
        //即时结算
        model('app/common/model/mall/shop/Settlement')->speedySettlement($order_id);
        //发送一条商家信息
        $to_user_id = \app\common\model\mall\shop\Shop::getFieldById($order['shop_id'],"user_id");
        $mobile = \app\common\model\mall\shop\Extra::getFieldByShopId($order['shop_id'],"applyLinkTel");
        $find = ['${ORDER_NO}','${GOODS}'];
        $replace = [$order['orderNo'],$orderGoods['goodsname']];

        $content = Msgtpl::getMsgByTpl('ORDER_SHOP_AUTO_DELIVERY', $find, $replace);
        if ($content != '') {
            Notification::record("客户已付款", $content, $this->actionname, $this->controllername, $order->id, $to_user_id);
            $template_id = 1;
            Hook::listen('vbot_send_msg', $template_id, [
                'content'         => $content,
                'at_mobiles'     => $mobile,
                'is_atall'       => 0,
            ]);
        }
        //发送一条用户信息
        $find = ['${ORDER_NO}','${GOODS}'];
        $replace = [$order['orderNo'],$orderGoods['goodsname']];
        $content = Msgtpl::getMsgByTpl('ORDER_USER_AUTO_DELIVERY', $find, $replace);
        if ($content != '') {
            Notification::record("下单成功", $content, "handleVirtualGoods", "order", $order['order_id'], $order["user_id"]);
            $mobile = \app\common\model\User::getFieldById($order['user_id'],"mobile");
            $template_id = 1;
            Hook::listen('vbot_send_msg', $template_id, [
                'content'         => $content,
                'at_mobiles'     => $mobile,
                'is_atall'       => 0,
            ]);
        }
        //发送管理短信
        $find = ['${ORDER_NO}'];
        $replace = [$order['orderNo']];
        $content = Msgtpl::getMsgByTpl('PHONE_ADMIN_PAY_ORDER', $find, $replace);
        if ($content != '') {
            Service::smsAdminNotice($content,'neworder');
        }

    }

    /**
     * 获取订单金额
     */
    public function getOrderPayInfo($obj){
        $user_id = (int)$obj["user_id"];
        $orderNo = $obj["orderNo"];
        $isBatch = (int)$obj["isBatch"];
        $where = ["user_id"=>$user_id,"status"=>"unpay","payis"=>0,"payType"=>1];
        $where["needPay"] = [">",0];
        if($isBatch==1){
            $where['orderunique'] = $orderNo;
        }else{
            $where['orderNo'] = $orderNo;
        }
        $orders = $this->where($where)->field('needPay')->select();
        if(empty($orders))return [];
        $needPay = 0;
        foreach($orders as $order){
            $needPay += $order['needPay'];
        }
        $data = array();
        $data["needPay"] = $needPay;
        return $data;
    }
    
    public function getOrderPayFrom($out_trade_no){
        $rs = $this->where(['orderNo|orderunique'=>$out_trade_no])->field('order_id,user_id,orderNo,orderunique')->find();
        if(!empty($rs)){
            $rs['isBatch'] = ($rs['orderunique'] == $out_trade_no)?1:0;
        }
        return $rs;
    }

    /**
     * 生成订单号
     */
    public static function OrderNo(){
        $order_id = Db::name('mall_order_orderids')->insertGetId(['rnd'=>time()]);
        return $order_id.(fmod($order_id,7));
    }

    /**
     * 获取订单统一流水号
     */
    public static function OrderQnique()
    {
        return (round(microtime(true), 4) * 10000) . mt_rand(1000, 9999);
    }

    public function goods()
    {
        return $this->hasMany('\app\common\model\mall\order\Goods', "order_id", "id");
    }

    public function log()
    {
        return $this->hasMany('\app\common\model\mall\order\Log', "order_id", "id");
    }
}
